package com.gy.api.mobile.company.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.gy.api.base.Constants;
import com.gy.api.base.R;
import com.gy.api.base.RsaKeyProperties;
import com.gy.api.base.Type;
import com.gy.api.mobile.company.dao.CompanyInfoDao;
import com.gy.api.mobile.company.domain.po.CompanyInfoPO;
import com.gy.api.mobile.company.domain.vo.*;
import com.gy.api.mobile.company.service.ICompanyService;
import com.gy.api.mobile.user.domain.vo.UpdateUserPasswordVO;
import com.gy.api.pc.examine.domain.vo.ExamineAddVO;
import com.gy.api.pc.examine.service.IExamineService;
import com.gy.api.pc.user.domain.vo.CompanyUserSearchVO;
import com.gy.api.pc.user.domain.vo.CompanyUserVO;
import com.gy.api.sms.service.DynamicMessageService;
import com.gy.exception.BusinessException;
import com.gy.util.EncryptionUtils;
import com.gy.util.RsaUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.security.PrivateKey;
import java.util.List;


@Service
@Transactional
@Slf4j
public class CompanyServiceImpl implements ICompanyService {


    @Autowired
    private RsaKeyProperties rsaKeyProperties;

    @Autowired
    private CompanyInfoDao companyInfoDao;

    @Autowired
    private DynamicMessageService smsService;

    @Autowired
    private IExamineService examineService;

    @Override
    public CompanyLoginResVO login(CompanyLoginVO companyLoginVO) {
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            companyLoginVO.setPassword(RsaUtils.decrypt(companyLoginVO.getPassword(), privateKey));
            companyLoginVO.setLoginName(RsaUtils.decrypt(companyLoginVO.getLoginName(), privateKey));
        }catch (Exception e){
//            e.printStackTrace();
            throw new BusinessException(Type.FAIL.getCode(),"密码错误");
        }
        Example sysExample = new Example(CompanyInfoPO.class);
        sysExample.and().andEqualTo("companyName",companyLoginVO.getLoginName())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        CompanyInfoPO loginUser=companyInfoDao.selectOneByExample(sysExample);
        if(loginUser==null){
            sysExample = new Example(CompanyInfoPO.class);
            sysExample.and().andEqualTo("companyCreditCode",companyLoginVO.getLoginName())
                    .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
            loginUser=companyInfoDao.selectOneByExample(sysExample);
        }
        if(loginUser==null){
            throw new BusinessException(Type.FAIL.getCode(),"密码错误");
        }
        if(!EncryptionUtils.match(loginUser.getId()+companyLoginVO.getPassword(),loginUser.getLoginPassword())){
            throw new BusinessException(Type.FAIL.getCode(),"账号密码错误！");
        }

        StpUtil.login(loginUser.getId(),"h5_company");
        CompanyLoginResVO companyLoginResVO =new CompanyLoginResVO();
        companyLoginResVO.setToken(StpUtil.getTokenValue());
        return companyLoginResVO;
    }


    @Override
    public void registerCompany(CompanyAddVO companyAddVO) throws Exception {
        Example sysExample = new Example(CompanyInfoPO.class);
        sysExample.and().andEqualTo("companyName",companyAddVO.getCompanyName())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        CompanyInfoPO companyInfoPO=companyInfoDao.selectOneByExample(sysExample);

        sysExample = new Example(CompanyInfoPO.class);
        sysExample.and().andEqualTo("companyCreditCode",companyAddVO.getCompanyCreditCode())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        CompanyInfoPO companyInfoCodePO=companyInfoDao.selectOneByExample(sysExample);

        if(companyInfoPO!=null){
            throw new BusinessException(Type.FAIL.getCode(),"该企业名称已注册，请勿重复提交注册。");
        }
        if(companyInfoCodePO!=null){
            throw new BusinessException(Type.FAIL.getCode(),"该统一社会信用代码已注册，请勿重复提交注册。");
        }

//        if(companyInfoPO==null){

        companyInfoPO=new CompanyInfoPO();
        BeanUtils.copyProperties(companyAddVO, companyInfoPO);
        companyInfoPO.preInsert();
        companyInfoPO.setCompanyState(2);

        String code= RandomUtil.randomString (6);
        smsService.sendDynamicMessage("【光影重庆】您好，企业信息注册成功，您的初始登录密码为:"+code+"，请不要泄漏给其他人。",companyInfoPO.getUserPhone());
        companyInfoPO.setLoginPassword(EncryptionUtils.encrypt(companyInfoPO.getId()+code));
        companyInfoDao.insertSelective(companyInfoPO);
//        }else{
//////            if(!companyInfoPO.getCompanyCreditCode().equals(companyAddVO.getCompanyCreditCode())){
//////                throw new BusinessException(Type.FAIL.getCode(),"企业信用代码错误！");
//////            }
////            if(companyInfoPO.getCompanyState()==1){
////                throw new BusinessException(Type.FAIL.getCode(),"该企业已认证请勿重复提交。");
////            }
////            //判断是否在流程中
////            // 存在正在处理中的该企业的办事认证申请，请等待平台核实结果。
////            if(examineService.checkExamine(companyInfoPO.getId())){
////                throw new BusinessException(Type.FAIL.getCode(),"存在正在处理中的该企业的办事认证申请，请等待平台核实结果。");
////            }
//        }
        //创建一个新的流程任务
        examineService.addExamine(new ExamineAddVO(companyInfoPO.getId(),Constants.EXAMINE_ENTERPRISE_CERTIFICATION[1],Constants.EXAMINE_3_USER,Constants.EXAMINE_TYPE_ENTERPRISE_CERTIFICATION
                ,companyInfoPO.getId(),companyInfoPO.getUserName()));

    }

    @Override
    public CompanyInfoVO getCompanyDesc(String companyId) {
        CompanyInfoPO companyInfoPO=companyInfoDao.selectByPrimaryKey(companyId);
        if(companyInfoPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),"信息未找到");
        }
        CompanyInfoVO vo=new CompanyInfoVO();
        BeanUtils.copyProperties(companyInfoPO, vo);
        return vo;
    }


    @Override
    public CompanyVO getCompanyOne() {
        CompanyInfoPO companyInfoPO=companyInfoDao.selectByPrimaryKey(StpUtil.getLoginId());
        if(companyInfoPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),"信息未找到");
        }
        CompanyVO companyVO=new CompanyVO();
        BeanUtils.copyProperties(companyInfoPO, companyVO);
        return companyVO;
    }

    @Override
    public void authentication(CompanyAuthenticationVO companyAuthenticationVO) {
        CompanyInfoPO companyInfoPO=companyInfoDao.selectByPrimaryKey(StpUtil.getLoginId());
        if(companyInfoPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR.getCode(),"信息未找到");
        }
        if(companyInfoPO.getCompanyState()==1){
            throw new BusinessException(Type.FAIL.getCode(),"该企业已认证请勿重复提交。");
        }
        //判断是否在流程中
        //存在正在处理中的该企业的办事认证申请，请等待平台核实结果。
        if(examineService.checkExamine(companyInfoPO.getId())){
            throw new BusinessException(Type.FAIL.getCode(),"存在正在处理中的该企业的办事认证申请，请等待平台核实结果。");
        }
        BeanUtils.copyProperties(companyAuthenticationVO, companyInfoPO);
        companyInfoPO.preUpdate();
        companyInfoDao.updateByPrimaryKeySelective(companyInfoPO);
        //创建一个新的流程任务
        examineService.addExamine(new ExamineAddVO(companyInfoPO.getId(),Constants.EXAMINE_ENTERPRISE_CERTIFICATION[1],Constants.EXAMINE_3_USER,Constants.EXAMINE_TYPE_ENTERPRISE_CERTIFICATION
                ,companyInfoPO.getId(),companyInfoPO.getUserName()));
    }

    @Override
    public void validateCompany(CompanyValidateVO validateVO) {
        Example sysExample = new Example(CompanyInfoPO.class);
        sysExample.and().andEqualTo("companyName",validateVO.getCompanyName())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        CompanyInfoPO companyInfoPO=companyInfoDao.selectOneByExample(sysExample);
        if(companyInfoPO==null){
            return;
        }
        if(companyInfoPO.getCompanyState()==1){
            throw new BusinessException(Type.FAIL.getCode(),"该企业已认证请勿重复提交。");
        }
        //判断是否在流程中
        if(examineService.checkExamine(companyInfoPO.getId())){
            throw new BusinessException(Type.FAIL.getCode(),"存在正在处理中的该企业的办事认证申请，请等待平台核实结果。");
        }
    }

    @Override
    public void validateCompanyState(CompanyValidateVO validateVO) {
        Example sysExample = new Example(CompanyInfoPO.class);
        sysExample.and().andEqualTo("companyName",validateVO.getCompanyName())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        CompanyInfoPO companyInfoPO=companyInfoDao.selectOneByExample(sysExample);
        if(companyInfoPO==null){
            throw new BusinessException(Type.FAIL.getCode(),"企业未注册。");
        }
        if(companyInfoPO.getCompanyState()==2){
            throw new BusinessException(Type.FAIL.getCode(),"企业未认证成功。");
        }

    }

    @Override
    public R<CompanyVO> validate_company_code(String companyCreditCode) {
        Example sysExample = new Example(CompanyInfoPO.class);
        sysExample.and().andEqualTo("companyCreditCode",companyCreditCode)
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        CompanyInfoPO companyInfoPO=companyInfoDao.selectOneByExample(sysExample);
        if(companyInfoPO==null){
            throw new BusinessException(Type.FAIL.getCode(),"未找到企业信息!");
        }
        CompanyVO companyVO=new CompanyVO();
        BeanUtils.copyProperties(companyInfoPO, companyVO);
        return new R(companyVO);
    }

    @Override
    public void updateCompanyPasswordVO(UpdateCompanyPasswordVO passwordVO) {
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            passwordVO.setPassword(RsaUtils.decrypt(passwordVO.getPassword(), privateKey));
        }catch (Exception e){
//            e.printStackTrace();
            throw new BusinessException(Type.FAIL.getCode(),"密码错误");
        }
        Example sysExample = new Example(CompanyInfoPO.class);
        sysExample.and().andEqualTo("companyCreditCode",passwordVO.getCompanyCreditCode())
                .andEqualTo("delFlag", Constants.DEL_FLAG_FALSE);
        CompanyInfoPO companyInfoPO=companyInfoDao.selectOneByExample(sysExample);
        if(companyInfoPO==null){
            throw new BusinessException(Type.FAIL.getCode(),"未找到企业信息!");
        }
        if(!companyInfoPO.getUserPhone().equals(passwordVO.getPhone())){
            throw new BusinessException(Type.FAIL.getCode(),"发人手机号码不匹配!");
        }
        companyInfoPO.setLoginPassword(EncryptionUtils.encrypt(companyInfoPO.getId()+passwordVO.getPassword()));
        companyInfoPO.preUpdate();
        companyInfoDao.updateByPrimaryKeySelective(companyInfoPO);
    }

    @Override
    public void updateOldPassword(UpdateUserPasswordVO updateUserPasswordVO) {
        try{
            PrivateKey privateKey = rsaKeyProperties.getPrivateKey();
            updateUserPasswordVO.setNewPassword(RsaUtils.decrypt(updateUserPasswordVO.getNewPassword(), privateKey));
            updateUserPasswordVO.setOldPassword(RsaUtils.decrypt(updateUserPasswordVO.getOldPassword(), privateKey));
        }catch (Exception e){
//            e.printStackTrace();
            throw new BusinessException(Type.FAIL.getCode(),"密码错误");
        }
        CompanyInfoPO companyInfoPO=companyInfoDao.selectByPrimaryKey(StpUtil.getLoginId());
        if(companyInfoPO==null){
            throw new BusinessException(Type.FAIL.getCode(),"未找到企业信息!");
        }
        if(!EncryptionUtils.match(companyInfoPO.getId()+updateUserPasswordVO.getOldPassword(),companyInfoPO.getLoginPassword())){
            throw new BusinessException(Type.FAIL.getCode(),"旧密码错误！");
        }
        companyInfoPO.setLoginPassword(EncryptionUtils.encrypt(companyInfoPO.getId()+updateUserPasswordVO.getNewPassword()));
        companyInfoPO.preUpdate();
        companyInfoDao.updateByPrimaryKeySelective(companyInfoPO);
    }

    @Override
    public List<CompanyUserVO> getList(CompanyUserSearchVO searchVO) {
        return companyInfoDao.getList(searchVO);
    }

    @Override
    public void import_excel() {
        ExcelReader reader = ExcelUtil.getReader("C:/Users/Administrator/Desktop/需增加企业账号202224.xlsx");
        List<List<Object>> readAll = reader.read(1);
        for (List<Object> one:readAll) {
            CompanyInfoPO companyInfoCodePO=new CompanyInfoPO();
            companyInfoCodePO.setCompanyName(one.get(0).toString());
            companyInfoCodePO.setCompanyCreditCode(one.get(1).toString());
//            companyInfoCodePO.setUserName(one.get(3).toString());
//            companyInfoCodePO.setUserPhone(one.get(4).toString());
            companyInfoCodePO.preInsert();
            companyInfoCodePO.setLoginPassword(EncryptionUtils.encrypt(companyInfoCodePO.getId()+"Gycq"+companyInfoCodePO.getCompanyCreditCode().substring(companyInfoCodePO.getCompanyCreditCode().length()-6)));
            companyInfoCodePO.setCompanyState(1);
            companyInfoDao.insertSelective(companyInfoCodePO);
        }
    }
}